import sys
import json
from http.client import responses

import requests
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render
from django.urls import reverse

from web.forms.file import FolderModelForm, FileModelForm
from web import models
from utils.tencent.cos import delete_file, delete_file_list, credential
from django.views.decorators.csrf import csrf_exempt
import logging


def file(request, project_id):
    """文件列表get & 添加文件夹psot"""
    parent_object = None
    folder_id = request.GET.get('folder', '')
    if folder_id.isdecimal():
        parent_object = models.FileRepository.objects.filter(id=folder_id, file_type=2,
                                                             project=request.tracer.project).first()
    # GET 查看文件列表
    if request.method == 'GET':
        """导航条"""
        breadcrumb_list = []
        parent = parent_object
        while parent:
            breadcrumb_list.insert(0, {'id': parent.id, 'name': parent.name})
            parent = parent.parent

        queeryset = models.FileRepository.objects.filter(project=request.tracer.project)
        if parent_object:
            file_object = queeryset.filter(parent=parent_object).order_by('-file_type')
        else:
            file_object = queeryset.filter(parent__isnull=True).order_by('-file_type')

        form = FolderModelForm(request, parent_object)
        context = {
            'form': form,
            'file_object': file_object,
            'breadcrumb_list': breadcrumb_list,
            'folder_object': parent_object,
        }
        return render(request, 'file.html', context)
    # POST 添加文件夹
    # 通过url来判断添加文件夹是在根目录添加文件夹还是在文件夹下面继续添加文件夹
    # http://127.0.0.1:8000/manage/1/file/?folder=9  在现有文件夹下面添加子文件夹
    # http://127.0.0.1:8000/manage/1/file/           在根目录下添加文件夹

    # 文件夹的添加&修改
    # 先获取fid
    fid = request.POST.get('fid', '')
    edit_object = None
    if fid.isdecimal():
        edit_object = models.FileRepository.objects.filter(id=int(fid), file_type=2,
                                                           project=request.tracer.project).first()
    if edit_object:
        form = FolderModelForm(request, parent_object, data=request.POST, instance=edit_object)
    else:
        form = FolderModelForm(request, parent_object, data=request.POST)
    if form.is_valid():
        form.instance.project = request.tracer.project
        form.instance.file_type = 2
        form.instance.update_user = request.tracer.user
        form.instance.parent = parent_object
        form.save()
        return JsonResponse({'status': True})
    return JsonResponse({'status': False, 'error': form.errors})


def file_delete(request, project_id):
    fid = request.GET.get('fid', '')
    # 删除数据库中的文件&文件夹（级连删除）
    delete_object = models.FileRepository.objects.filter(id=fid, project=request.tracer.project).first()
    if delete_object.file_type == 1:
        # 删除文件（数据库文件删除、cos文件删除、项目已使用空间容量恢复）
        # 处理已使用空间
        request.tracer.project.user_space -= delete_object.file_size
        request.tracer.project.save()
        # cos中删除文件
        delete_file(request.tracer.project.bucket, request.tracer.project.region, delete_object.key)

        # 在数据库中删除文件
        delete_object.delete()
        return JsonResponse({'status': True})
    else:
        # 删除文件夹（找到文件夹下所有文件--》数据库文件删除、cos文件删除、项目已使用空间容量恢复
        # delete_object
        # 找他下面的文件和文件夹
        # 删除cos文件及文件夹
        total_size = 0
        key_list = []
        folder_list = [delete_object, ]
        for folder in folder_list:
            child_list = models.FileRepository.objects.filter(project=request.tracer.project, parent=folder).order_by(
                '-file_type')
            for child in child_list:
                if child.file_type == 2:
                    folder_list.append(child)
                else:
                    total_size += child.file_size
                    key_list.append({'Key': child.key})
        if key_list:
            delete_file_list(request.tracer.project.bucket, request.tracer.project.region, key_list)

        # 归还容量
        if total_size:
            request.tracer.project.user_space -= total_size
            request.tracer.project.save()
        # 删除数据库文件
        delete_object.delete()
        return JsonResponse({'status': True})


@csrf_exempt
def cos_credential(request, project_id):
    # 做容量限制：单文件限制&总容量
    total_size = 0
    per_file_limit = request.tracer.price_policy.per_file_size * 1024 * 1024
    file_list = json.loads(request.body.decode('utf-8'))
    for item in file_list:
        # 单文件限制(涉及字节和m的转换)
        if item['size'] > per_file_limit:
            msg = '单文件超出限制（最大{}M），文件：{},请升级套餐'.format(per_file_limit, item['name'])
            return JsonResponse({'status': False, 'error': msg})
        total_size += item['size']
        # 对总容量进行限制
        # pricepolicy中的限制
        total_file_limit = request.tracer.price_policy.project_space * 1024 * 1024 * 1024
        # 已使用空间
        if total_size + request.tracer.project.user_space > total_file_limit:
            return JsonResponse({'status': False, 'error': '容量超过限制，请升级套餐'})
    # 通过之后获取临时凭证，并返回给前端
    data_dict = credential(request.tracer.project.bucket, request.tracer.project.region)
    return JsonResponse({'status': True, 'data': data_dict})


@csrf_exempt
def file_post(request, project_id):
    form = FileModelForm(request, data=request.POST)
    if form.is_valid():
        # 通过modelform.save()存储到数据库中的数据返回的instance对象，无法通过get_xx_display后去choice的中文
        # form.instance.file_type = 1
        # form.update_user = request.tracer.user
        # instance = form.save()

        # 通过models来进行存储
        data_dict = form.cleaned_data
        data_dict.pop('etag')
        data_dict.update({'project': request.tracer.project, 'file_type': 1, 'update_user': request.tracer.user})
        instance = models.FileRepository.objects.create(**data_dict)
        # 当前项目的已使用空间更新
        request.tracer.project.user_space += data_dict['file_size']
        request.tracer.project.save()

        result={
            'id': instance.id,
            'name': instance.name,
            'file_size': instance.file_size,
            'username': instance.update_user.username,
            'date_time':instance.update_datetime.strftime('%Y年%m月%d日 %H:%M'),
            'file_type': instance.get_file_type_display(),
            'download_url':reverse('web:file_download',kwargs={'project_id':project_id,'file_id':instance.id} ),
        }
        return JsonResponse({'status': True, 'data': result})

    return JsonResponse({'status': False, 'data': '文件错误'})


def file_download(request, project_id,file_id):
    # 打开文件，获取文件内容，去cos获取文件内容
    file_object=models.FileRepository.objects.filter(id=file_id, project=request.tracer.project).first()
    res=requests.get(file_object.file_path)
    data=res.content
    response=HttpResponse(data, content_type='application/octet-stream')
    # 设置响应头
    response['Content-Disposition']="attachment; filename={};".format(file_object.name)
    return response
